package set

import (
	"go-utils/set/set_interface"
	"sync"
)

func CreateSet() set_interface.SetInterface {
	s := &set{
		m: make(map[interface{}]interface{}),
	}
	return s
}

func CreateSyncSet() set_interface.SetInterface {
	s := &syncSet{}
	return s
}

type set struct {
	m map[interface{}]interface{}
}

func (s *set) Clear() {
	s.m = make(map[interface{}]interface{})
}

func (s *set) Exist(v interface{}) bool {
	_, ok := s.m[v]
	return ok
}

func (s *set) Empty() bool {
	return len(s.m) == 0
}
func (s *set) Add(v interface{}) {
	s.m[v] = 1
}

func (s *set) Delete(v interface{}) {
	delete(s.m, v)
}

func (s *set) Size() int {
	return len(s.m)
}
func (s *set) Values() []interface{} {
	vs := make([]interface{}, 0)
	for v := range s.m {
		vs = append(vs, v)
	}
	return vs
}

type syncSet struct {
	m     sync.Map
	count int
	mutex sync.RWMutex
}

func (s *syncSet) getCount() int {
	s.mutex.RLocker()
	defer s.mutex.RLocker()
	return s.count
}

func (s *syncSet) countChange(num int) {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	s.count += num
}

// Clear 时间复杂度比较高，建议新建个对象来代替情况操作
func (s *syncSet) Clear() {
	vs := s.Values()
	for _, v := range vs {
		s.Delete(v)
	}
}

func (s *syncSet) Exist(v interface{}) bool {
	_, ok := s.m.Load(v)
	return ok
}

func (s *syncSet) Empty() bool {
	return s.getCount() == 0
}
func (s *syncSet) Add(v interface{}) {
	if _, ok := s.m.Load(v); !ok {
		s.m.Store(v, 1)
		s.countChange(1)
	}
}

func (s *syncSet) Delete(v interface{}) {
	if _, ok := s.m.Load(v); ok {
		s.m.Delete(v)
		s.countChange(-1)
	}
}

func (s *syncSet) Size() int {
	return s.getCount()
}

func (s *syncSet) Values() []interface{} {
	vs := make([]interface{}, 0)
	s.m.Range(func(key, value any) bool {
		vs = append(vs, key)
		return true
	})
	return vs
}
